﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using BlackBBS.Models.Data;
using BlackBBS.Infrastructure.Repository;
using BlackBBS.Extensions;
using System.Xml;
using System.Xml.Serialization;
namespace BlackBBS.Tests
{
    [TestClass]
    public class RepositoryTests
    {
        private string UserFilename = null;
        private string SessionFilename = null;
        private string TestPassword = null;
        private string TestLogin = null;

        public RepositoryTests()
        {
            this.UserFilename = @"C:\bbs\db\" + typeof(User).ToString().Replace(".", "_") + ".xml";
            this.SessionFilename = @"C:\bbs\db\" + typeof(Session).ToString().Replace(".", "_") + ".xml";
            this.TestPassword = "bingo99";
            this.TestLogin = "CmdrTallen";
        }


        [TestMethod]
        public void Test_Repository()
        {
            using (var db = new XMLRepository<User>(this.UserFilename))
            {
                long userId = 1;
                var user = db.Get(userId);
                if (user != null)
                {
                    db.Delete(userId);
                    user = db.Get(userId);
                    Assert.IsTrue(user == null, "Repository Not Successfully Deleting User");
                }
                var newUser = new User
                {
                    Login = "CmdrTallen",
                    Id = db.NextId(),
                    Firstname = "Steven",
                    Lastname = "Hildreth",
                    Birthday = DateTime.Parse("04/13/1971")
                };
                db.Save(newUser);
                var newUserFetch = db.Get(newUser.Id);
                Assert.IsTrue(newUserFetch.Equals(newUser), "DB Save or Get Failed");
            }
        }

        [TestMethod]
        public void Test_Repository_Get_All_Users()
        {
            using (var db = new XMLRepository<User>(this.UserFilename))
            {
                var users = db.GetAll();
                Assert.IsTrue(users.Count() > 0, "User Collection Not Returned From Repository");
            }
        }

        [TestMethod]
        public void Test_Repository_Get_User_By_Login()
        {
            using (var db = new XMLRepository<User>(this.UserFilename))
            {
                var userLogin = "CmdrTallen";
                var user = User.GetUserByLogin(db, userLogin);
                Assert.IsTrue(user != null, "User Fetch Failed");
                Assert.IsTrue(user.Login.Equals(userLogin), "User Fetch Failed");
            }
        }

        [TestMethod]
        public void Test_Flush_Sessions()
        {
            using (var db = new XMLRepository<Session>(this.SessionFilename))
            {
                foreach (var session in db.GetAll())
                {
                    db.Delete(session.Id);
                }
            }
        }

        [TestMethod]
        public void Test_Make_100_Sessions()
        {
            var sessionCount = 100;
            using (var db = new XMLRepository<Session>(this.SessionFilename))
            {
                foreach (var session in db.GetAll())
                {
                    db.Delete(session.Id);
                }
            }
            using (var db = new XMLRepository<Session>(this.SessionFilename))
            {
                var user = new User()
                {
                    Id = 1,
                    Login = "CmdrTallen",
                    Firstname = "Steven"
                };

                for (var i = 0; i < sessionCount; i++)
                {
                    var session = new Session
                    {
                        Created = DateTime.Now,
                        Node = 0,
                        User = user
                    };
                    db.Save(session);
                }
            }

            using (var db = new XMLRepository<Session>(this.SessionFilename))
            {
                var sessions = db.GetAll();
                Assert.IsTrue(sessions.Count().Equals(sessionCount), "Session Testing Failed");
            }
        }

        [TestMethod]
        public void Test_Repository_Set_User_Password()
        {
            using (var db = new XMLRepository<User>(this.UserFilename))
            {
                var user = User.GetUserByLogin(db, this.TestLogin);
                Assert.IsTrue(user != null, "User Fetch Failed");
                Assert.IsTrue(user.Login.Equals(this.TestLogin), "User Fetch Failed");

                user.SetPassword(this.TestPassword);
                db.Save(user);

                var user2 = User.GetUserByLogin(db, this.TestLogin);
                Assert.IsTrue(user2.Password.Equals(this.TestPassword.Hash()), "Hash compare failed");
                Assert.IsTrue(user2.AuthenticateUser(this.TestPassword), "Authentication Failed");
            }
        }

        [TestMethod]
        public void Test_Repository_Authenticate_User()
        {
            var dbFilename = typeof(User).ToString();
            using (var db = new XMLRepository<User>(this.UserFilename))
            {
                var user = User.GetUserByLogin(db, this.TestLogin);
                Assert.IsTrue(user.AuthenticateUser(this.TestPassword), "Authentication Failed");
            }
        }
        
    }
}
